﻿using AutoMapper;
using AutoMapper.Configuration;
using CBLibrary.Repository.Dto;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using RepositoryTestWeb.AppService;
using RepositoryTestWeb.AppService.Goods;
using RepositoryTestWeb.AppService.Log;
using RepositoryTestWeb.AppService.Order;
using RepositoryTestWeb.DbContext;
using System;
using System.Linq;
using System.Reflection;

namespace RepositoryTestWeb.BootStrapper
{
    public static class DependencyInjectionExtensions
    {
        #region 反射加载实体映射
        /// <summary>
        /// 反射加载实体映射
        /// </summary>
        /// <param name="services"></param>
        public static void AddAutoMapper(this IServiceCollection services)
        {
            var expression = new MapperConfigurationExpression();

            var types = typeof(UserDto).GetTypeInfo().Assembly.DefinedTypes
                .Where(t => t.IsSubclassOf(typeof(DtoBase)) && !t.IsAbstract)
                .Select(t => t.AsType());

            foreach (var type in types)
            {
                var dto = (DtoBase)Activator.CreateInstance(type);
                dto.CreateMap(expression);
            }

            var config = new MapperConfiguration(expression);

            services.AddSingleton<IMapper>(sp => config.CreateMapper());
        }
        #endregion

        #region 注入应用服务
        /// <summary>
        /// 注入应用服务
        /// </summary>
        /// <param name="services"></param>
        public static void AddAppService(this IServiceCollection services)
        {
            services.AddScoped<IUserService, UserService>();
            services.AddScoped<ILogService, LogService>();
            services.AddScoped<IOrderService, OrderService>();
            services.AddScoped<IGoodsService, GoodsService>();
        }
        #endregion

        #region 数据库初始化
        /// <summary>
        /// 数据库初始化
        /// </summary>
        /// <param name="app"></param>
        public static void InitializeDatabase(this IApplicationBuilder app)
        {
            using (var scope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
            {
                var context = scope.ServiceProvider.GetRequiredService<TestDbContext>();

                //1. 生成迁移脚本
                // dotnet ef migrations add Init

                //2. 执行自动迁移
                context.AutoMigration();

                //3. 写入种子数据
                //IMPORTANT:生成迁移脚本之前(生成数据表前) ****不得执行数据初始化****, 否则会抛异常
                context.EnsureSeedData();
            }
        }
        #endregion
    }
}
